Functional Dependencies
関連論文
引数同士の関数関係を明示する
これを
code:purs(hs)
class Stream stream element where
uncons :: stream -> Maybe { head :: element, tail :: stream }
こう書く
code:purs(hs)
class Stream stream element | stream -> element where
uncons :: stream -> Maybe { head :: element, tail :: stream }
「stream型決まれば、element型が一意に決まる」ということを明示できる
なるほどmrsekut.icon
つまり、この制限を加えると他のStream String なんかの定義はできないということかmrsekut.icon
試してみるmrsekut.icon
例
code:purs(hs)
class Stream stream element | stream -> element where
uncons :: stream -> Maybe { head :: element, tail :: stream }
instance streamArray :: Stream (Array a) a where
uncons = Array.uncons
instance streamString :: Stream String String.CodePoint where
uncons = String.uncons
instance streamString :: Stream String Int where -- error!!
uncons xs = Just { head: 1, tail: xs }
instance streamString :: Stream Int String.CodePoint where -- error!!
uncons xs = Just { head: String.codePointFromChar 'c', tail: xs }
確かにエラーになったmrsekut.icon
下に書いたほうがエラーになる
コドメインが被っていてもエラーになる
Stream String なんかもStream なんか CodePointもエラー
全単射じゃないといけないのかmrsekut.icon
例
code:purs(hs)
class Union (left :: # Type) (right :: # Type) (union :: # Type)
| left right -> union, right union -> left, union left -> right
3つの型引数を取っている
その中の任意の2つの型が決まれば、残りの一つも決まる、ということを言っっている
例
code:purs(hs)
class Cons (label :: Symbol) (a :: k) (tail :: Row k) (row :: Row k)
| label a tail -> row, label row -> a tail
4つの型引数を取っている
label, a, tailと、label, rowの組み合わせに関しては、これが決まれば残りも一意に決まる、ということを言っている
psのRow型の型クラスにもやたら出てくるmrsekut.icon